(document.loader || (document.loader = [])).push(["verify", function (require, exports, module) {
    class VerifyOption {
        constructor(src, father, id = "") {
            if (!father instanceof Verify) throw Error("You're not my father.");
            this._index = father._opts.length;
            this._id = id;
            this._src = src;
            this._father = father;
            this.$el = $('<img class="app-verify-option">');
            this.$el.attr("data-index", this._index);
            this.$el.attr("id", id);
            this.$el.on("click", event => {
                this._father._event("onOptionClick", {
                    target: this,
                    id: this._id,
                    index: this._index,
                    src: this._src,
                    clickEvent: event
                });
            });
            this.setSrc(src);
            this.setAlt("选项" + this._index);
        };
        setSrc(src) {
            this.$el.attr("src", src);
        };
        setAlt(alt) {
            this.$el.attr("alt", alt);
        };
        remove() {
            this.$el.remove();
        };
    };

    class Verify {
        constructor() {
            this.$el = null;
            this.$img = null;
            this.$opt = null;
            this._opts = [];
            this.$tit = null;
            this._callback = new Map();
        };
        get opened() {
            return this.$el ? (this.$el.hasClass("app-verify-open")) : false
        };
        get isLoading() {
            return this.$el ? (this.$el.hasClass("app-verify-load")) : false
        };
        loadElement() {
            var verify = $('<div class="app-verify"></div>');
            var question = $('<div class="app-verify-question"></div>');
            var options = $('<div class="app-verify-options"></div>');
            var text = $('<p class="app-verify-question-text"></p>');
            var img = $('<img class="app-verify-question-img">');
            var reset = $('<div class="app-verify-question-reset"></div>');
            var reset_span = $('<span></span>');
            var reset_a = $('<a></a>');
            var reset_img = $('<img>');
            var reset_text = document.createTextNode("");
            verify.append(question, options);
            question.append(text, img, reset);
            reset.append(reset_span, reset_a);
            reset_a.append(reset_img, reset_text);
            reset_text.data = "刷新";
            reset_span.text("看不清？");
            reset_img.attr("src", "/static/image/reset.svg");
            reset_img.attr("alt", "刷新");
            img.attr("alt", "选择");
            this.$el = verify;
            this.$img = img;
            this.$opt = options;
            this.$tit = text;
            verify.appendTo(document.body);

            reset_a.on("click", (event) => {
                this._event("onResetClick", event);
            });
        };
        startLoading() {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$el.addClass("app-verify-load");
        };
        stopLoading() {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$el.removeClass("app-verify-load");
        };
        open() {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$el.addClass("app-verify-show");
            var overlay = document.createElement('div');
            overlay.style.position = 'fixed';
            overlay.style.top = '0';
            overlay.style.left = '0';
            overlay.style.width = '100%';
            overlay.style.height = '100%';
            overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // 半透明黑色背景
            overlay.style.zIndex = '99999999'; // 确保遮罩层在最顶层
            document.body.appendChild(overlay);
            this.$overlay = overlay;
        };
        close() {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$el.removeClass("app-verify-show");
            this.$overlay.remove();
        };
        remove() {
            this.stopLoading();
            this.close();
            setTimeout(() => {
                this.$el.remove();
                this.$el = null;
                this.$img = null;
                this.$opt = null;
                this.$tit = null;
            }, this.opened ? 300 : 1000 / 16)
        };
        setTitle(title) {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$tit.text(title);
        };
        setImg(src) {
            if (!this.$el) throw Error("Please initialize the element first.");
            this.$img.attr("src", src);
        };
        addOption(src, id = "") {
            if (!this.$el) throw Error("Please initialize the element first.");
            const opt = new VerifyOption(src, this, id);
            this._opts.push(opt);
            this.$opt.append(opt.$el);
        };
        clearOptions() {
            this._opts.forEach(option => {
                option.remove();
            });
            this._opts = [];
        };
        on(name, callback) {
            this._callback.set(callback, name);
        };
        off(callback) {
            this._callback.delete(callback);
        };
        _event(eventName, data) {
            this._callback.forEach((name, callback) => {
                if (name == eventName) {
                    callback(data);
                }
            })
        }
    };

    class Derive {
        constructor() {
        };
        getData() {
            return new Promise((resolve, reject) => {
                var xhr = new XMLHttpRequest();
                var url = "/api/Imgverify/make";

                xhr.open("POST", url, true);
                xhr.setRequestHeader("Content-Type", "application/json");

                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        var response = JSON.parse(xhr.responseText);
                        if (response.code == 200) {
                            var data = response.data;

                            var verify_id = new Date();
                            verify_id.setTime(verify_id.getTime() + (240 * 1000));
                            document.cookie = "verify_id=" + data.id + "; expires=" + verify_id.toUTCString();

                            resolve(data);
                        } else {
                            reject(response.msg);
                        }
                    }
                };

                xhr.send();
            })

        }
        start() {
            return new Promise((resolve) => {
                let id = "";

                var verify = new Verify();
                verify.loadElement();
                verify.setTitle("请选择与此图内容相同的图片\n（不分大小写）");
                for (let i in "0".repeat(4)) {
                    verify.addOption("", "");
                }

                verify.open();
                verify.startLoading();

                this.getData().then(data => {
                    id = data.id;

                    verify.stopLoading();
                    verify.clearOptions();
                    verify.setImg(data.question);

                    for (let { base, id } of data.choose) {
                        verify.addOption(base, id);
                    }

                    verify.on("onOptionClick", ({ id: _id }) => {
                        verify.startLoading();

                        // 当选项点击
                        var postData = {
                            id,
                            choose: _id
                        };

                        $.post('/api/Imgverify/check', postData, function (data) {
                            verify.remove();

                            data = JSON.parse(data)
                            if (data.code == 200) {
                                resolve(id);
                                swal("验证成功", "", "success");
                            } else {
                                resolve(null);
                                swal("验证失败", data.msg, "error");
                            }
                        });
                    });

                    verify.on("onResetClick", () => {
                        verify.startLoading();

                        this.getData().then(data => {
                            id = data.id;

                            verify.stopLoading();
                            verify.setImg("");
                            verify.clearOptions();

                            verify.setImg(data.question);
                            for (let { base, id } of data.choose) {
                                verify.addOption(base, id);
                            }
                        }, msg => {
                            verify.stopLoading();
                            alert(msg);
                        })
                    });

                }, msg => {
                    alert(msg);
                    resolve(null);
                    verify.remove();
                })
            })
        };
    }

    module.exports = new Derive();
}])